// Created: Dec 13, 2014
//
// Author: wjinwen.1988@gmail.com

#ifndef CHI_NET_CONNECTOR_H
#define CHI_NET_CONNECTOR_H

#include <stdint.h>

#include <string>
#include <memory>

#include <event.h>

#include "chi/net/callbacks.h"
#include "chi/net/inet_address.h"
#include "chi/net/channel.h"

namespace chi {
namespace net {

class EventLoop;

class Connector {
 public:
  Connector(EventLoop* loop, const InetAddress& server_addr);
  ~Connector();

  void set_new_conn_cb(const NewConnectionCallback& cb);

  void Start();   // can be called in any thread.
  void Restart(); // can be called in any thread.
  void Stop();    // can be called in any thread.

  const InetAddress& server_addr() const { return server_addr_; }
 private:
  enum States { kDisconnected, kConnecting, kConnected };
  static const int kMaxRetryDelayMs;
  static const int kInitRetryDelayMs;

  void set_state(States s) { state_ = s; }
  void StartInLoop();
  void StopInLoop();
  void Connect();
  void Retry(int sockfd);
  void Connecting(int sockfd);
  int RemoveAndResetChannel();
  void ResetChannel();
  void HandleWrite();
  void HandleError();

  EventLoop* loop_;
  std::unique_ptr<Channel> channel_;
  InetAddress server_addr_;
  bool connect_;
  States state_;
  NewConnectionCallback new_conn_cb_;
  int retry_delay_ms_;
};

} 
}

#endif 
